package frege.control.Alternative where

--import frege.prelude.PreludeMonad 
--import frege.control.Monoid

infixl 3 `<|>` 

class Alternative (Empty f, Applicative f) => f where
    (<|>) :: f a -> f a -> f a

{-
-- | One or more.
some :: f a -> f [a]
some v = some_v
      where
        many_v = some_v <|> pure []
        some_v = (:) <$> v <*> many_v

-- | Zero or more.
many :: f a -> f [a]
many v = many_v
      where
        many_v = some_v <|> pure []
        some_v = (:) <$> v <*> many_v
-}

-- instances for Prelude types

--instance Empty Maybe where
--  empty = Nothing
--  null Nothing = true
--  null _ = false

--instance Alternative Maybe where
--    Nothing <|> p = p
--    Just x <|> _ = Just x

--instance Alternative [] where
--    (<|>) = (++)

-- new instances

--data Const a b = Const { getConst :: a }

--instance Functor Const m where
--    fmap _ (Const v) = Const v

--instance Applicative (Monoid m) => Const m where
--    return _ = Const mempty
--    Const f <*> Const v = Const (f `mappend` v)


-- | Lists, but with an 'Applicative' functor based on zipping, so that
--
-- @f '<$>' 'ZipList' xs1 '<*>' ... '<*>' 'ZipList' xsn = 'ZipList' (zipWithn f xs1 ... xsn)@
--
--data ZipList a = ZipList { getZipList :: [a] }

--instance Functor ZipList where
--    fmap f (ZipList xs) = ZipList (map f xs)

--instance Applicative ZipList where
--    return x = ZipList (repeat x)
--    ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)

-- | One or none.
--optional :: Alternative f => f a -> f (Maybe a)
--optional v = fmap Just v <|> return Nothing
